using System;
using System.Reflection;

using System.IO;
using System.Text;
using Microsoft.SharePoint;
using System.Xml;
using System.Xml.Schema;
using System.Collections;
using SharePoint.ImportExport.Core;



namespace SharePoint2003Import
{
	/// <summary>
	/// This is a helper class
	/// </summary>
	internal class Miscellaneous
	{
	
		private static int XmlParseErrorCount=0;
		/// <summary>
		/// 
		/// </summary>
		/// <param name="listFields"></param>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public static string GetInternalFieldName(ArrayList listFields, string fieldName)
		{
			int i=0;
			string foundFieldName="";
			if(null==listFields)
				return fieldName;
			for (i=listFields.Count-1 ;i>0;i--)
			{
				SPField field=(SPField)listFields[i];
				if(field.Title == fieldName || field.InternalName==fieldName)
				{
					foundFieldName=field.InternalName;
					break;
				}
			}
			return foundFieldName;
			
		}
		/*
		/// <summary>
		/// 
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="xmlItemsNode"></param>
		/// <returns></returns>
		public static string GetField(string fieldName, XmlNode xmlItemsNode)
		{
			string field = "";
			try
			{
				XmlNodeList fieldNodes = xmlItemsNode.SelectNodes("field");
				foreach(XmlNode fieldNode in fieldNodes)
				{
					if(fieldNode.SelectSingleNode("name").InnerText == fieldName)
					{
						field = fieldNode.SelectSingleNode("value").InnerText;
						break;
					}
				}
			}
			catch (Exception e)
			{
				System.Diagnostics.Debug.WriteLine(e.Message);
			}
			return field;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="xmlItemNode"></param>
		/// <param name="defaultValue"></param>
		/// <returns></returns>
		public static string GetNodeValue(string fieldName, XmlNode xmlItemNode, string defaultValue)
		{
			string field = defaultValue;
			try
			{
				field = xmlItemNode.SelectSingleNode(fieldName).InnerText;
			}
			
			catch
			{
			}
			return field;
		}
		*/
		/// <summary>
		/// This method checks that the file conforms to the schema definition
		/// </summary>
		/// <param name="xmlFileName"></param>
		/// <param name="xsdFile"></param>
		/// <returns></returns>
		public static bool CheckXmlFile(string xmlFileName, string xsdFile)
		{
			if(!File.Exists(xmlFileName))
			{
				Logger.Log(ErrorLevel.Information,"Could not open the file: "+xmlFileName);
				return true;
			}
			XmlParseErrorCount=0;
			XmlTextReader xmlReader = new XmlTextReader(xmlFileName); 
			XmlValidatingReader validatingXmlRdr = new XmlValidatingReader(xmlReader);

			Stream stream = null;
			XmlTextReader xmlSchemaRdr = null;

			Assembly thisAssembly = Assembly.GetExecutingAssembly();
				      
			// get the specified xsd
			stream = thisAssembly.GetManifestResourceStream(xsdFile);
			xmlSchemaRdr = new XmlTextReader(stream);

			validatingXmlRdr.ValidationType = ValidationType.Schema ;
			validatingXmlRdr.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);

				
			//Load the xml document using the XMLValidationReader
			try
			{
				validatingXmlRdr.Schemas.Add("", xmlSchemaRdr);  
				while (validatingXmlRdr.Read());
			}
			catch(XmlSchemaException xmlSchemaEx)
			{
				Logger.Log(ErrorLevel.Error,"XML file does not conform to schema. Error: "+xmlSchemaEx.Message);  
				return false;
			}
			

			catch(XmlException xmlEx)
			{
				Logger.Log(ErrorLevel.Error,"XML file does not conform to schema. Error: "+xmlEx.Message);  
				return false;
			}
			finally
			{
				if(null != stream) stream.Close();
				if(null != xmlSchemaRdr ) xmlSchemaRdr.Close();
				if(null != validatingXmlRdr) validatingXmlRdr.Close();
				if(null != xmlReader) xmlReader.Close();
			}
			if(XmlParseErrorCount>0)
				return false;
			else
				return true;


		}
		//Validation handler logs validation errors(if any) and maintains the error count
		private static void ValidationHandler(object sender, ValidationEventArgs args)
		{
			XmlParseErrorCount++;
			Logger.Log(ErrorLevel.Information,"***XML Validation error\tMessage: " +  args.Message); //LogID: ImportFileParser_ValidationHandler_2
		}
		/// <summary>
		/// Helper function for removing characters not allowed in SharePoint. 
		/// </summary>
		/// <param name="stringToBeFixed"></param>
		/// <returns>A string that SharePoint acceps</returns>
		public static string FixName(string stringToBeFixed)
		{
			string str=stringToBeFixed;
			char[] escapeChars = {'?','=',':',';',']','[','/','\\','*','>','<','|','&','%','#','~'};
	
			if(-1 != str.IndexOfAny(escapeChars))
			{

				str = str.Replace("?","_");
				str = str.Replace("=","_");
				str = str.Replace(":","_");
				str = str.Replace("/","_");
				str = str.Replace("\\","_");
				str = str.Replace("*","_");
				str = str.Replace(">","_");
				str = str.Replace("<","_");
				str = str.Replace("|","_");

				// The following are not valid in WSS
				// Todo:  get a comprehensive list of bad characters for WSS.....add below.

				str = str.Replace("&"," And ");  
				str = str.Replace("%"," PCT ");
				str = str.Replace("#","_");
				str = str.Replace("~","_");
				str = str.Replace("[","_");
				str = str.Replace("]","_");
				//RPC fails if ; is in the string
				str = str.Replace(";","_");
			}
			return str;

		}

	}
}
